﻿// <copyright file="INetwork.cs" company="City of Portland, BES-ASM">
// </copyright>
// <summary>INetwork interface</summary>

namespace BESASM.EMGAATS.BusinessClasses
{
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Threading.Tasks;

  /// <summary>
  /// Interface for <see cref="Network"/>
  /// </summary>
  public interface INetwork
  {
    /// <summary>
    /// Gets the nodes of the Network
    /// </summary>
    EntityCollection<INode> Nodes { get; }

    /// <summary>
    /// Gets the links of the Network
    /// </summary>
    EntityCollection<ILink> Links { get; }

    /// <summary>
    /// Gets the cross sections of the Network
    /// </summary>
    EntityCollection<ICrossSection> CrossSections { get; }

    /// <summary>
    /// Gets the weirs of the Network
    /// </summary>
    EntityCollection<IWeir> Weirs { get; }

    /// <summary>
    /// Gets the orifices of the Network
    /// </summary>
    EntityCollection<IOrifice> Orifices { get; }

    /// <summary>
    /// Gets the areas of the Network
    /// </summary>
    EntityCollection<IArea> Areas { get; }

    /// <summary>
    /// Gets the directors of the Network
    /// </summary>
    EntityCollection<IDirector> Directors { get; }

    /// <summary>
    /// Gets the infiltrators of the Network
    /// </summary>
    EntityCollection<IInfiltrator> Infiltrators { get; }

    /// <summary>
    /// Gets the storages of the Network
    /// </summary>
    EntityCollection<IStorage> Storages { get; }

    /// <summary>
    /// Creates a node for the Network
    /// </summary>
    /// <returns>A reference to the created Node</returns>
    INode CreateNode();

    /// <summary>
    /// Create a node for the Network
    /// </summary>
    /// <param name="id">ID of the Node</param>
    /// <returns>A reference to the created Node</returns>
    INode CreateNode(int id);

    /// <summary>
    /// Create an Orifice for the Network
    /// </summary>
    /// <returns>The created orifice</returns>
    IOrifice CreateOrifice();

    /// <summary>
    /// Create an Orifice for the Network
    /// </summary>
    /// <param name="id">The ID of the Orifice</param>
    /// <returns>The created Orifice</returns>
    IOrifice CreateOrifice(int id);

    /// <summary>
    /// Create a Weir for the Network
    /// </summary>
    /// <returns>The created Weir</returns>
    IWeir CreateWeir();

    /// <summary>
    /// Create a Weir for the Network
    /// </summary>
    /// <param name="id">The ID of the Weir</param>
    /// <returns>The created Weir</returns>
    IWeir CreateWeir(int id);

    /// <summary>
    /// Create an Infiltrator for the network
    /// </summary>
    /// <returns>The created Infiltrator</returns>
    IInfiltrator CreateInfiltrator();

    /// <summary>
    /// Create an Infiltrator for the Network
    /// </summary>
    /// <param name="id">The ID of the Infiltrator</param>
    /// <returns>The created Infiltrator</returns>
    IInfiltrator CreateInfiltrator(int id);

    /// <summary>
    /// Create Link for the Network
    /// </summary>
    /// <returns>The created Link</returns>
    ILink CreateLink();

    /// <summary>
    /// Creates a link for the Network
    /// </summary>
    /// <param name="id">ID of the Link</param>
    /// <returns>A reference to the created Link</returns>
    ILink CreateLink(int id);

    /// <summary>
    /// Creates a cross section for the Network
    /// </summary>
    /// <returns>A reference to the created CrossSection</returns>
    ICrossSection CreateCrossSection();

    /// <summary>
    /// Creates a cross section for the Network
    /// </summary>
    /// <param name="id">ID of the CrossSection</param>
    /// <returns>A reference to the created CrossSection</returns>
    ICrossSection CreateCrossSection(int id);

    /// <summary>
    /// Creates an Area for the Network
    /// </summary>
    /// <returns>The created Area</returns>
    IArea CreateArea();

    /// <summary>
    /// Creates an Area for the Network
    /// </summary>
    /// <param name="id">The ID of the Area</param>
    /// <returns>The created Area</returns>
    IArea CreateArea(int id);

    /// <summary>
    /// Creates a Director for the Network
    /// </summary>
    /// <returns>The created director</returns>
    IDirector CreateDirector();

    /// <summary>
    /// Creates a Director for the Network
    /// </summary>
    /// <param name="id">The ID of the Director</param>
    /// <returns>The created Director</returns>
    IDirector CreateDirector(int id);

    /// <summary>
    /// Creates a Storage for the Network
    /// </summary>
    /// <returns>The created storage</returns>
    IStorage CreateStorage();

    /// <summary>
    /// Creates a Storage for the Network
    /// </summary>
    /// <param name="id">The ID of the Storage</param>
    /// <returns>The created Storage</returns>
    IStorage CreateStorage(int id);

    /// <summary>
    /// Creates an Entity
    /// </summary>
    /// <typeparam name="T">The type of Entity</typeparam>
    /// <returns>The created Entity</returns>
    T CreateEntity<T>() where T : IEntity;

    /// <summary>
    /// Creates an Entity for the Network
    /// </summary>
    /// <typeparam name="T">A class that implements IEntity</typeparam>
    /// <param name="id">The ID of the Entity</param>
    /// <returns>A reference to the created Entity</returns>
    T CreateEntity<T>(int id) where T : IEntity;

    /// <summary>
    /// Adds an entity to the network
    /// </summary>
    /// <typeparam name="T">The type of the entity.</typeparam>
    /// <param name="entity">The entity to add to the network.</param>
    void Add<T>(T entity) where T : IEntity;

    /// <summary>
    /// Clears the network of all entities
    /// </summary>
    void Clear();

    /// <summary>
    /// Extracts a subnetwork of the network by copying all entities related to the given links into a new Network.
    /// </summary>
    /// <param name="linkIds">The IDs of the links to extract for making the subnetwork.</param>
    /// <returns>A new Network containing copies of all the specified links and associated entities.</returns>
    INetwork ExtractSubnetwork(IList<int> linkIds);

    /// <summary>
    /// Optimizes lookup of related (e.g. upstream) entities. Only valid until the network is modified.
    /// </summary>
    void Optimize();
  }
}
